/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!
 * \file conv2d_config.h
 * \brief
 */

#ifndef CONV2D_CONFIG_H
#define CONV2D_CONFIG_H

#include "kernel_utils.h"
#include "conv2d_framework_util.h"

using namespace AscendC;

namespace conv2d {

enum class Conv2dCfgTypeID {
    CONV2D_ID_UNKNOWN = 0,
    CONV2D_ID_NORMAL,
    CONV2D_ID_TEST,
    CONV2D_ID_END
};

enum class ConvFormat {
    ND = 0,
    NCHW,
    NHWC,
    NC1HWC0,
    FRACTAL_Z,
};

struct ConvParam {
    __aicore__ inline ConvParam() {};
};

template <typename T> struct GetDstType {
    using Type = T;
};

template <> struct GetDstType<half> {
    using Type = float;
};

template <> struct GetDstType<bfloat16_t> {
    using Type = float;
};
 
template <> struct GetDstType<float> {
    using Type = float;
};

template <> struct GetDstType<int8_t> {
    using Type = int32_t;
};

template <TPosition POSITION, ConvFormat FORMAT, typename TYPE>
struct Conv2dType {
    constexpr static TPosition pos = POSITION;
    constexpr static ConvFormat format = FORMAT;
    using T = TYPE;
};

template<class FMAP_TYPE, class WEIGHT_TYPE, class OUTPUT_TYPE, class BIAS_TYPE, class CONV_CFG>
struct Conv2dDataType {
    using ConvParam = CONV_CFG;
    using FmapT = typename FMAP_TYPE::T;
    using WeightT = typename WEIGHT_TYPE::T;
    using OutputT  = typename OUTPUT_TYPE::T;
    using BiasT = typename BIAS_TYPE::T;
    using ScaleT = uint64_t;
    using L0cT  = typename GetDstType<FmapT>::Type;

    constexpr static uint32_t configID = (uint32_t)Conv2dCfgTypeID::CONV2D_ID_NORMAL;
    constexpr static uint32_t implType = (uint32_t)Conv2dCfgTypeID::CONV2D_ID_NORMAL;
    constexpr static uint32_t intfType = (uint32_t)Conv2dCfgTypeID::CONV2D_ID_NORMAL;

    constexpr static auto formatA = FMAP_TYPE::format;
    constexpr static auto formatB = WEIGHT_TYPE::format;
    constexpr static auto formatC = OUTPUT_TYPE::format;
    constexpr static auto formatBias = BIAS_TYPE::format;

    constexpr static auto posA = FMAP_TYPE::pos;
    constexpr static auto posB = WEIGHT_TYPE::pos;
    constexpr static auto posC = OUTPUT_TYPE::pos;
    constexpr static auto posBias = BIAS_TYPE::pos;

    using ContextData = struct _ { __aicore__ inline _(){} };
};


template<class Conv2dDataType>
struct Conv2dCfg : public Conv2dDataType {
public:
    __aicore__ inline Conv2dCfg() {}
    using ContextData = struct _ : public Conv2dDataType::ContextData {
        __aicore__ inline _() {}
    };
};
}  // namespace conv2d

#endif // __CONV2D_CONFIG_H__
